#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
测试运行脚本
用于执行所有单元测试并生成测试报告
"""

import os
import sys
import subprocess
import time
import json
from datetime import datetime


def run_tests_with_coverage():
    """运行测试并生成覆盖率报告"""
    print("=" * 60)
    print("开始运行单元测试...")
    print("=" * 60)

    # 设置环境变量
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')

    # 运行测试命令
    test_commands = [
        # 基础测试
        "python manage.py test home_application.tests.HostListApiTest -v 2",
        "python manage.py test home_application.tests.LogSearchApiTest -v 2",
        "python manage.py test home_application.tests.LogBackupApiTest -v 2",
        "python manage.py test home_application.tests.BackupRecordApiTest -v 2",
        "python manage.py test home_application.tests.ApiStatisticsTest -v 2",
        "python manage.py test home_application.tests.BusinessApiTest -v 2",
        "python manage.py test home_application.tests.SetApiTest -v 2",
        "python manage.py test home_application.tests.ModuleApiTest -v 2",
        "python manage.py test home_application.tests.HostDetailApiTest -v 2",
        "python manage.py test home_application.tests.ModelTest -v 2",
        "python manage.py test home_application.tests.ExceptionHandlingTest -v 2",
        "python manage.py test home_application.tests.IntegrationTest -v 2",
        # 运行所有测试
        "python manage.py test home_application.tests -v 2",
    ]

    results = []

    for cmd in test_commands:
        print(f"\n执行命令: {cmd}")
        print("-" * 40)

        try:
            start_time = time.time()
            result = subprocess.run(
                cmd.split(),
                capture_output=True,
                text=True,
                timeout=300  # 5分钟超时
            )
            end_time = time.time()

            execution_time = end_time - start_time

            if result.returncode == 0:
                print("✅ 测试通过")
                status = "PASS"
            else:
                print("❌ 测试失败")
                print(f"错误输出: {result.stderr}")
                status = "FAIL"

            print(f"执行时间: {execution_time:.2f}秒")

            results.append({
                'command': cmd,
                'status': status,
                'execution_time': execution_time,
                'stdout': result.stdout,
                'stderr': result.stderr,
                'returncode': result.returncode
            })

        except subprocess.TimeoutExpired:
            print("⏰ 测试超时")
            results.append({
                'command': cmd,
                'status': 'TIMEOUT',
                'execution_time': 300,
                'stdout': '',
                'stderr': 'Test timeout after 300 seconds',
                'returncode': -1
            })
        except Exception as e:
            print(f"❌ 执行异常: {str(e)}")
            results.append({
                'command': cmd,
                'status': 'ERROR',
                'execution_time': 0,
                'stdout': '',
                'stderr': str(e),
                'returncode': -1
            })

    return results


def generate_test_report(results):
    """生成测试报告"""
    print("\n" + "=" * 60)
    print("生成测试报告...")
    print("=" * 60)

    # 统计结果
    total_tests = len(results)
    passed_tests = len([r for r in results if r['status'] == 'PASS'])
    failed_tests = len([r for r in results if r['status'] == 'FAIL'])
    timeout_tests = len([r for r in results if r['status'] == 'TIMEOUT'])
    error_tests = len([r for r in results if r['status'] == 'ERROR'])

    total_time = sum(r['execution_time'] for r in results)

    # 生成报告
    report = {
        'timestamp': datetime.now().isoformat(),
        'summary': {
            'total_tests': total_tests,
            'passed_tests': passed_tests,
            'failed_tests': failed_tests,
            'timeout_tests': timeout_tests,
            'error_tests': error_tests,
            'success_rate': (passed_tests / total_tests * 100) if total_tests > 0 else 0,
            'total_execution_time': total_time
        },
        'results': results
    }

    # 保存报告到文件
    report_file = f"test_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
    with open(report_file, 'w', encoding='utf-8') as f:
        json.dump(report, f, ensure_ascii=False, indent=2)

    # 打印摘要
    print(f"\n测试摘要:")
    print(f"总测试数: {total_tests}")
    print(f"通过: {passed_tests} ✅")
    print(f"失败: {failed_tests} ❌")
    print(f"超时: {timeout_tests} ⏰")
    print(f"异常: {error_tests} 💥")
    print(f"成功率: {report['summary']['success_rate']:.1f}%")
    print(f"总执行时间: {total_time:.2f}秒")
    print(f"详细报告已保存到: {report_file}")

    return report


def run_specific_test(test_class=None, test_method=None):
    """运行特定的测试"""
    if test_class and test_method:
        cmd = f"python manage.py test home_application.tests.{test_class}.{test_method} -v 2"
    elif test_class:
        cmd = f"python manage.py test home_application.tests.{test_class} -v 2"
    else:
        cmd = "python manage.py test home_application.tests -v 2"

    print(f"运行特定测试: {cmd}")
    result = subprocess.run(cmd.split(), capture_output=True, text=True)

    if result.returncode == 0:
        print("✅ 测试通过")
    else:
        print("❌ 测试失败")
        print(f"错误输出: {result.stderr}")

    print(f"输出: {result.stdout}")
    return result.returncode == 0


def main():
    """主函数"""
    if len(sys.argv) > 1:
        command = sys.argv[1]

        if command == "specific":
            # 运行特定测试
            test_class = sys.argv[2] if len(sys.argv) > 2 else None
            test_method = sys.argv[3] if len(sys.argv) > 3 else None
            run_specific_test(test_class, test_method)
        elif command == "coverage":
            # 运行覆盖率测试
            print("运行覆盖率测试...")
            subprocess.run([
                "coverage", "run", "--source=home_application",
                "manage.py", "test", "home_application.tests"
            ])
            subprocess.run(["coverage", "report"])
            subprocess.run(["coverage", "html"])
        else:
            print("未知命令")
            print("用法:")
            print("  python run_tests.py                    # 运行所有测试")
            print("  python run_tests.py specific           # 运行所有测试")
            print("  python run_tests.py specific HostListApiTest  # 运行特定测试类")
            print("  python run_tests.py specific HostListApiTest test_host_list_success  # 运行特定测试方法")
            print("  python run_tests.py coverage           # 运行覆盖率测试")
    else:
        # 运行所有测试
        results = run_tests_with_coverage()
        generate_test_report(results)


if __name__ == "__main__":
    main()